local assets = {
	Asset("ANIM", "anim/player_basic.zip"),
	Asset("ANIM", "anim/musha_body_shadow.zip"),
	Asset("SOUND", "sound/maxwell.fsb"),
	Asset("SOUND", "sound/willow.fsb"),
	Asset("ANIM", "anim/swap_pickaxe.zip"),
	Asset("ANIM", "anim/swap_axe.zip"),
	Asset("ANIM", "anim/swap_nightmaresword.zip")
}

local items = {
	AXE = "swap_axe",
	PICK = "swap_pickaxe",
	SWORD = "swap_nightmaresword"
}

local function OnAttacked(inst, data)
	inst.components.combat:SuggestTarget(data.attacker)
	inst.components.combat:ShareTarget(
		data.attacker,
		30,
		function(dude)
			return dude.components.follower and dude.components.follower.leader == inst.components.follower.leader
		end,
		5
	)
end

local function EquipItem(inst, item)
	if item then
		inst.AnimState:OverrideSymbol("swap_object", item, item)
		inst.AnimState:Hide("ARM_normal")
		inst.AnimState:Show("ARM_carry")
	end
end

local function Retarget(inst)
	return FindEntity(
		inst,
		TUNING.HOUND_TARGET_DIST,
		function(guy)
			return guy.prefab ~= inst.prefab and guy.entity:IsVisible() and not guy.components.health:IsDead() and
				guy ~= (inst or inst.components.follower.leader) and
				not (not guy.components.follower or
					(guy.components.follower.leader and guy.components.follower.leader == inst.components.follower.leader)) and
				not guy:HasTag("player") and
				not guy:HasTag("companion") and
				not guy:HasTag("wall")
		end,
		{"_combat", "_health"},
		{"prey"}
	)
end

local function onusemusha(inst, data)
	inst.Light:Enable(true)
	inst.sg:GoToState("hit")
	inst.SoundEmitter:PlaySound("dontstarve/common/gem_shatter")
	if not TheWorld.state.isnight then
		inst.components.fueled:StartConsuming()
	end
	inst.components.sleeper:WakeUp()
end
local function offusemusha(inst, data)
	inst.sg:GoToState("stunned")
	inst.Light:Enable(false)
	inst.SoundEmitter:PlaySound("dontstarve/common/fireOut")
	inst.components.fueled:StopConsuming()
end

local function fn()
	local inst = CreateEntity()
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddSoundEmitter()
	inst.entity:AddDynamicShadow()
	inst.entity:AddNetwork()

	inst.Transform:SetFourFaced(inst)

	MakeGhostPhysics(inst, 1, .5)
	RemovePhysicsColliders(inst)

	inst.AnimState:SetBank("wilson")
	inst.AnimState:SetBuild("musha_body_shadow")
	inst.AnimState:PlayAnimation("idle")

	inst.AnimState:Hide("ARM_carry")
	inst.AnimState:Hide("hat")
	inst.AnimState:Hide("hat_hair")

	inst:AddTag("notraptrigger")
	inst:AddTag("companion")
	inst:AddTag("noauradamage")

	--[[ if inst.DLC2_fly then
		MakeAmphibiousCharacterPhysics(inst, 2, .5)
	end ]]
	inst:AddComponent("colourtweener")
	inst.components.colourtweener:StartTween({1, 1, 1, .7}, 0)
	inst.entity:AddLight()
	inst.Light:SetRadius(.3)
	inst.Light:SetFalloff(.5)
	inst.Light:SetIntensity(.3)
	inst.Light:SetColour(50 / 255, 50 / 255, 50 / 255)

	inst:AddComponent("talker")
	inst.components.talker.fontsize = 22
	inst.components.talker.colour = Vector3(0.7, 0.75, 0.95, 1)

	inst.entity:SetPristine()

	if not TheWorld.ismastersim then
		return inst
	end

	inst:AddComponent("inspectable")
	inst:AddComponent("locomotor")

	inst.components.locomotor.pathcaps = {ignorecreep = true}
	inst.components.locomotor.walkspeed = TUNING.WILSON_WALK_SPEED
	inst.components.locomotor.runspeed = TUNING.WILSON_RUN_SPEED

	inst:AddComponent("follower")
	inst.components.follower:KeepLeaderOnAttacked()
	inst.components.follower.keepdeadleader = true

	inst:AddComponent("combat")
	inst.components.combat.playerdamagepercent = 0
	inst.components.combat.hiteffectsymbol = "torso"
	inst.components.combat:SetRetargetFunction(1, Retarget)
	inst.components.combat:SetRange(2, 3)
	inst.components.combat:SetDefaultDamage(TUNING.SHADOWWAXWELL_DAMAGE)

	inst:AddComponent("health")
	inst.components.health:SetMaxHealth(150)
	inst.components.health:SetAbsorptionAmount(0.75)
	inst.components.health:StartRegen(1, 3)
	inst.components.health.fire_damage_scale = 0
	inst.components.health.nofadeout = true

	inst:AddComponent("inventory")
	inst.components.inventory.dropondeath = false

	inst:AddComponent("sleeper")
	inst.components.sleeper:SetResistance(4)

	inst:AddComponent("fueled")
	inst.components.fueled:InitializeFuelLevel(300)
	inst.components.fueled.rate = 1
	inst.components.fueled.accepting = false
	inst.components.fueled:SetDepletedFn(inst.components.health.Kill)
	inst.components.fueled:StopConsuming()

	inst:SetStateGraph("SGmusha_shadow")

	inst:AddComponent("machine")
	inst.components.machine.turnonfn = onusemusha
	inst.components.machine.turnofffn = offusemusha
	inst.components.machine.cooldowntime = 0
	inst.components.machine:TurnOn()

	inst:AddComponent("eater")
	inst.components.eater.PrefersToEat = function(self, food)
		if food.prefab == "nightmarefuel" then
			return true
		else
			return false
		end
	end
	inst.components.eater:SetOnEatFn(
		function(inst, food)
			if food.prefab == "nightmarefuel" then
				inst.components.fueled:SetPercent(1)
			end
		end
	)

	inst.items = items
	inst.equipfn = EquipItem

	inst:ListenForEvent(
		"death",
		function(inst)
			SpawnPrefab("statue_transition").Transform:SetPosition(inst:GetPosition():Get())
			inst.SoundEmitter:PlaySound("dontstarve/common/fireOut")
		end
	)
	inst:ListenForEvent(
		"onhitother",
		function(inst, data)
			local other = data.target
			if other and other:HasTag("_musha") then
				inst.components.combat:SetTarget(nil)
				inst.components.combat:GiveUp()
			end
			if not (other:HasTag("smashable")) and other then
				if other.components.health then
					inst.components.health:DoDelta(10)
					inst.components.fueled:DoDelta(15)
				end
				if other.components.freezable then
					other.components.freezable:AddColdness(1)
					other.components.freezable:SpawnShatterFX()
				end
				if other.components.burnable and other.components.burnable:IsBurning() then
					other.components.burnable:Extinguish()
				end
			end
		end
	)
	inst:ListenForEvent("attacked", OnAttacked)
	inst:WatchWorldState(
		"isnight",
		function(inst, isnight)
			if not isnight and inst.components.machine.ison then
				inst.components.fueled:StartConsuming()
			else
				inst.components.fueled:StopConsuming()
			end
		end
	)

	local brain = require "brains/musha_shadowbrain"
	inst:SetBrain(brain)

	return inst
end

return Prefab("musha_shadow", fn, assets)
